#pragma once

#include "trm/compressed_mask.h"
#include <imglib/gdiplus.h>
#include <imglib/hexcode.h>
#include <xml/stream.h>
#include <sstream>

namespace trm {

void compressed_grey_mask::store(grey_mask const & m)
{
	// PNG has a specific passion of seeking the output stream 
	// before writing which leads to a stream failure.
	// So we just need to put something in first.
	code_.str(".");
	code_.clear();
	code_.seekp(0);
	if (!m.empty())
		code_ << img::gdiplus(m, img::png_format);
}

void compressed_grey_mask::extract(grey_mask & m) const
{
	if (empty())
		m.clear();
	else {
		code_.clear(); ///clear() should precede seekg(...), otherwise seekg may fail and read fails also
		code_.seekg(0);
		code_ >> img::gdiplus(m);
	}
}

std::ostream & compressed_grey_mask::write_hex(std::ostream & out) const
{
	img::ostream_hex_iterator i(out);
	code_.clear(); ///clear() should precede seekg(...), otherwise seekg may fail and writing fails also
	code_.seekg(0);
	for (;;) {
		int c = code_.get();
		if (c == encoding::traits_type::eof())
			break;
		*i = c;
		++i;
	}
	return out;
}

std::istream & compressed_grey_mask::read_hex(std::istream & in)
{
	img::istream_hex_iterator i(in);

	code_.str(std::string());
	code_.clear();
	while (i != img::istream_hex_iterator()) {
		code_.put(*i);
		++i;
	}

	return in;
}

xml::stream & compressed_grey_mask::serialize(xml::stream & s)
{
	using namespace xml;
	if (s.in()) {
		std::string hexstring;
		s || def_attr("encoded", hexstring, string());
		read_hex(std::istringstream(hexstring));
	}
	else {
		if (!empty()) {
			std::ostringstream hex;
			write_hex(hex);
			s || attr("encoded", hex.str());
		}
	}
	return s;
}

} //namespace trm
